home *** CD-ROM | disk | FTP | other *** search
Wrap
/* Justification Layout Sample Program By Eric Mader, After Mike Fairman, Oliver Steele et. al. 1.0B2 (MD, 09/09/93) -- insert GXIgnoreGraphicsNotice calls so we're not notified that we're setting the text size to the default of 12 points. */ /* Copyright ©1989, 1990, 1991 Apple Computer, Inc. All rights reserved. */ #ifndef THINK_C #include <Quickdraw.h> #include <Fonts.h> #include <Windows.h> #include <Dialogs.h> #include <Events.h> #include <Memory.h> #include <Menus.h> #include <String.h> #include <Desk.h> #include <Script.h> #include <ToolUtils.h> #define thePort qd.thePort #define screenBits qd.screenBits #endif #include "graphics libraries.h" #include "qd library.h" #include "graphics debugging.h" #include "graphics routines.h" #include "graphics toolbox.h" #include "layout types.h" #include "layout routines.h" #include "layout library.h" /* This macro is useful for constructing fixed values */ #define f(a,b) (((fixed) (a) << 16) + (b)) /* various menu and dialog things */ enum {aboutDLOG = 128, appleMenuID = 128, fileMenuID, editMenuID}; /* resource ID's */ enum {okButton = 1, showsItem, authorItem}; enum { /* Apple Menu */ aboutCommand = 1, /* File Menu */ quitCommand = 1, /* Edit Menu */ undoCommand = 1, cutCommand, copyCommand, pasteCommand, clearCommand}; WindowPtr myWindow, whichWindow; gxViewPort myPort; Rect qdWindowRect; Rect growRect = {40, 40, 32767, 32767}; Rect bigRect = {-32768, -32768, 32767, 32767}; gxRectangle windowRect; MenuHandle appleMenu, fileMenu, editMenu; Boolean done = false; gxColor colorWhite = xRGB (0xFFFF, 0xFFFF, 0xFFFF); /* white */ gxColor hsvInitial = xHSV (0, 0xFFFF, 0xFFFF); /* red */ static void ShowAboutBox () { GrafPtr savePort; DialogPtr theDialog; short itemType; Handle itemHdl; Rect itemRect; short itemHit; GetPort(&savePort); theDialog = GetNewDialog(aboutDLOG, nil, (WindowPtr) -1); SetPort(theDialog); GetDItem(theDialog, authorItem, &itemType, &itemHdl, &itemRect); SetIText(itemHdl, (StringPtr) "\pRice Dream"); GetDItem(theDialog, showsItem, &itemType, &itemHdl, &itemRect); SetIText(itemHdl, (StringPtr) "\pJustification"); do { ModalDialog(nil, &itemHit); } while (itemHit != okButton); CloseDialog(theDialog); SetPort(savePort); } static void SetupMenus () { InsertMenu (appleMenu = GetMenu (appleMenuID), 0); AddResMenu (appleMenu, (ResType) 'DRVR'); InsertMenu (fileMenu = GetMenu (fileMenuID), 0); InsertMenu (editMenu = GetMenu (editMenuID), 0); DrawMenuBar (); } static void DoMenuCommand (long mResult) { short theItem = LoWord (mResult), theMenuID = HiWord (mResult); GrafPtr savePort; Str255 daName; switch (theMenuID) { case appleMenuID: if (theItem == aboutCommand) ShowAboutBox (); else { GetItem (appleMenu, theItem, daName); GetPort (&savePort); (void) OpenDeskAcc (daName); SetPort (savePort); } break; case fileMenuID: if (theItem == quitCommand) done = true; break; case editMenuID: break; } HiliteMenu (0); } static void DrawMargins(fixed top, fixed bottom, fixed margin, fixed width) { gxLine bound; bound.first.x = margin; bound.first.y = top; bound.last.x = margin; bound.last.y = bottom; GXDrawLine(&bound); bound.first.x += width; bound.last.x += width; GXDrawLine(&bound); } void main() { EventRecord theEvent; gxShape layout1, layout2, layout3, layout4, whiteOut; gxRunControls controls; gxLayoutOptions gxLayoutOptions; StyleRunOverrides overrides; gxPriorityJustificationOverride allToSpace, allToChar; char *text1 = "The gxLine Layout Manager is a set of support routines"; char *text2 = "that client programs can call to implement certain"; char *text3 = "functions. It is not a text editor or word processor,"; char *text4 = "although it could certainly be used to implement"; gxPoint posn; GDHandle max; short mbh = GetMBarHeight (); MaxApplZone(); MoreMasters(); MoreMasters(); SetGraphicsLibraryErrors(); SetGraphicsLibraryNotices (); /*GXSetValidation(gxInternalValidation | gxStructureValidation | gxNoMemoryManagerValidation); /* uncomment this for less speed and more error-checking */ InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus (); InitCursor(); SetupMenus (); /* find the deepest monitor, and make a window that just covers it */ max = GetMaxDevice (&bigRect); qdWindowRect = (**max).gdRect; /* bring it down one mbh for the header, maybe another if on main screen */ if (qdWindowRect.top == 0 && qdWindowRect.left == 0) qdWindowRect.top += mbh; qdWindowRect.top += mbh; InsetRect (&qdWindowRect, 4, 4); ShortRectToFixed (&qdWindowRect, &windowRect); myWindow = NewWindow(nil, &qdWindowRect, (StringPtr) "\pJustification Layout Sample", true, documentProc, (WindowPtr) -1L, true, 0L); myPort = GXNewWindowViewPort (myWindow); SetDefaultViewPort (myPort); /* When we want to erase the whole window, we just GXDrawShape (whiteOut). */ whiteOut = GXNewShape(gxFullType); GXSetShapeColor (whiteOut, &colorWhite); /* Make a default RuntControls, gxLayoutOptions and StyleRunOverrides */ InitializeRunControls (&controls); InitializeLayoutOptions (&gxLayoutOptions); InitializeStyleRunOverrides (&overrides); /* Set the PriorityJustOverride records to default values */ SetDefaultPriorityJustOverride (&allToSpace); SetDefaultPriorityJustOverride (&allToChar); /* Set the unlimited grow flag for white space, which will cause the entire justification gap to be assigned to white space characters */ allToSpace.deltas[gxWhiteSpacePriority].growFlags |= (gxOverrideUnlimited | gxUnlimitedGapAbsorption); /* Set the unlimited grow flag for inter character, which will cause the entire justification gap to be assigned to inter character spacing. Also override the inter character priority to "kashida" which is the highest priority. This will guarantee that inter character spacing is adjusted in favor of white space. */ allToChar.deltas[gxInterCharPriority].growFlags |= (gxOverrideUnlimited | gxUnlimitedGapAbsorption | gxOverridePriority | gxKashidaPriority); /* We'll set the text to about twice the width really needed so that the justification effects are clearly visible. */ gxLayoutOptions.width = ff(468); /* 6.5 inches * 72 points per inch */ gxLayoutOptions.just = fract1; /* full justification */ /* Compute the position that would center a layout's baseline in the window. We'll draw the lines 30 points apart, so we'll put the first two 45 and 15 points above this position and the second two 15 and 45 points below it. */ posn.x = ((windowRect.right - windowRect.left) - gxLayoutOptions.width) / 2; posn.y = ((windowRect.bottom - windowRect.top) / 2) - ff(45); /* Build a layout for each gxLine */ GXIgnoreGraphicsNotice(text_size_already_set); layout1 = NewSingleLayout ( text1, (char *) "\pTimes Roman", ff(12), &gxLayoutOptions, &posn, 0, &controls, nil, 0, nil); GXPopGraphicsNotice(); posn.y += ff(30); GXIgnoreGraphicsNotice(text_size_already_set); layout2 = NewSingleLayout ( text2, (char *) "\pTimes Roman", ff(12), &gxLayoutOptions, &posn, 0, &controls, nil, 0, nil); GXPopGraphicsNotice(); posn.y += ff(30); overrides.priorityJustOverride = &allToSpace; GXIgnoreGraphicsNotice(text_size_already_set); layout3 = NewSingleLayout ( text3, (char *) "\pTimes Roman", ff(12), &gxLayoutOptions, &posn, 0, &controls, nil, 0, &overrides); GXPopGraphicsNotice(); posn.y += ff(30); overrides.priorityJustOverride = &allToChar; GXIgnoreGraphicsNotice(text_size_already_set); layout4 = NewSingleLayout ( text4, (char *) "\pTimes Roman", ff(12), &gxLayoutOptions, &posn, 0, &controls, nil, 0, &overrides); GXPopGraphicsNotice(); GXDrawShape (layout1); GXDrawShape (layout2); GXDrawShape (layout3); GXDrawShape (layout4); DrawMargins(posn.y - ff(105), posn.y + ff(15), posn.x, gxLayoutOptions.width); /* Now just spin in a simple event loop until it's time to go */ while (!done) { if (WaitNextEvent(everyEvent, &theEvent, 0, nil)) { switch(theEvent.what) { case mouseDown: switch (FindWindow(theEvent.where, &whichWindow)) { case inSysWindow: SystemClick(&theEvent, whichWindow); break; case inMenuBar: DoMenuCommand (MenuSelect (theEvent.where)); break; case inDrag: DragWindow(whichWindow, theEvent.where, &screenBits.bounds); break; case inGrow: { register long newSize; newSize = GrowWindow(whichWindow, theEvent.where, &growRect); SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), true); } break; case inGoAway: if (TrackGoAway(whichWindow, theEvent.where)) done = true; break; case inContent: if (whichWindow != FrontWindow()) SelectWindow(whichWindow); break; } break; case keyDown: case autoKey: if (myWindow == FrontWindow () && theEvent.modifiers & cmdKey) DoMenuCommand (MenuKey (theEvent.message & charCodeMask)); break; case updateEvt: BeginUpdate((WindowPtr)theEvent.message); GXDrawShape (whiteOut); GXDrawShape (layout1); GXDrawShape (layout2); GXDrawShape (layout3); GXDrawShape (layout4); DrawMargins(posn.y - ff(105), posn.y + ff(15), posn.x, gxLayoutOptions.width); EndUpdate((WindowPtr)theEvent.message); break; } } } /* dispose everything we've allocated. */ /* If we forget something, we'll get a warning when we call GXExitGraphics */ GXDisposeShape (layout1); GXDisposeShape (layout2); GXDisposeShape (layout3); GXDisposeShape (layout4); DisposeWindow(myWindow); GXDisposeShape (whiteOut); }